"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 故障&可靠性测试
Case Name   : 数据目录异常时创建数据库
Create At   : 2021/01/05
@zou_jialiang0505328126
Description :
    1.删除base目录权限
    2.创建数据库
    3.恢复权限
    4.创建数据库
    5.删除base目录
    6.创建数据库
    7.恢复base目录
    8.创建数据库
Expect      :
    1.无
    2.创建失败，提示无权限Permission denied
    3.无
    4.创建 成功
    5.无
    6.创建失败提示文件夹丢失The database subdirectory "base/16385" is missing
    7.无
    8.创建成功
History     :
    modified by @wan005 at 2022.08.11:增加checkpoint和主备同步，优化base的恢复方式
    modified by @wan005 at 2022.08.11:增加循环删除base目录
"""

import os
import time
import unittest
from yat.test import macro
from yat.test import Node
from testcase.utils.CommonSH import CommonSH
from testcase.utils.CommonSH import RestartDbCluster
from testcase.utils.Common import Common
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class Ddldatabase(unittest.TestCase):
    commonshpri = CommonSH('PrimaryDbUser')
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info('-----Opengauss_Reliability_Dbsys_Case228.py 开始执行----')
        self.db_primary_db_user = Node(node='PrimaryDbUser')
        self.db_primary_root_node = Node(node='PrimaryRoot')
        self.constant = Constant()
        self.common = Common('PrimaryRoot')
        self.basepath = os.path.join(macro.DB_INSTANCE_PATH, 'base')
        self.dbname = 'testdb'

    def test_basebackup(self):
        self.log.info('-------------1.删除base目录权限---------------------')
        cmd = f"chmod 000 {self.basepath}"
        result = self.db_primary_db_user.sh(cmd).result()
        self.log.info(result)

        self.log.info('-------------------2.创建数据库-----------------')
        sql = f'create database {self.dbname};'
        result = self.commonshpri.executDbSql(sql)
        self.log.info(result)
        self.assertIn(self.constant.PERMISSION_DENIED, result)

        self.log.info('------------3.恢复base目录权限-------------------')
        cmd = f"chmod 700 {self.basepath}"
        result = self.db_primary_db_user.sh(cmd).result()
        self.log.info(result)

        self.log.info('-------------------4.创建数据库-----------------')
        sql = f'create database {self.dbname};drop database {self.dbname};'
        result = self.commonshpri.executDbSql(sql)
        self.log.info(result)
        self.assertIn(self.constant.CREATE_DATABASE_SUCCESS_MSG, result)
        self.assertIn(self.constant.drop_database_success_msg, result)

        self.log.info('-------------等待主备同步-------------')
        result = self.commonshpri.executDbSql("checkpoint")
        self.log.info(result)
        self.assertIn("CHECKPOINT", result, "执行失败:checkpoint")
        result = self.commonshpri.check_location_consistency('primary', 3)
        self.assertTrue(result, "执行失败:等待主备同步")

        self.log.info('-------------5.删除base目录-------------')
        cmd = f"cp -r {self.basepath} " \
            f"{self.basepath}_baktest"
        self.log.info(cmd)
        result = self.db_primary_db_user.sh(cmd).result()
        self.log.info(result)

        cmd = f"rm -rf {self.basepath}"
        is_del = True
        for i in range(10):
            time.sleep(3)
            result = self.db_primary_db_user.sh(cmd).result()
            self.log.info(result)
            if not result.strip():
                is_del = False
                break
        if is_del:
            raise Exception("删除base目录失败，请检查")

        self.log.info('-------------------6.创建数据库-----------------')
        result = self.commonshpri.executDbSql(f'create database {self.dbname};')
        self.log.info(result)
        self.assertIn(self.constant.NOT_EXIST, result)
        self.assertIn('is missing', result)

        self.log.info('---------7.恢复base目录-------------')
        result = self.db_primary_db_user.sh(
            f"cp -r {self.basepath}_baktest {self.basepath}").result()
        self.log.info(result)

        self.log.info('-------------------8.创建数据库-----------------')
        sql = f'create database {self.dbname};drop database {self.dbname};'
        result = self.commonshpri.executDbSql(sql)
        self.log.info(result)
        self.assertIn(self.constant.CREATE_DATABASE_SUCCESS_MSG, result)
        self.assertIn(self.constant.drop_database_success_msg, result)

    def tearDown(self):
        self.log.info('-------------------------环境清理---------------')
        self.log.info('----------------------恢复base目录权限---------------')
        stop_result = self.commonshpri.stopDbInstance()
        self.log.info(stop_result)
        result = self.db_primary_db_user.sh(f"rm -rf {self.basepath} && "
                    f"mv {self.basepath}_baktest {self.basepath} && "
                    f"chmod 700 {self.basepath}").result()
        self.log.info(result)
        start_result = self.commonshpri.startDbInstance()
        self.log.info(start_result)
        self.log.info('-----------------------删除数据库-----------------------')
        sql = f'drop database if exists {self.dbname};'
        drop_result = self.commonshpri.executDbSql(sql)
        self.log.info(drop_result)
        self.assertEqual("", result, "执行失败:恢复base目录权限")
        self.assertIn(self.constant.drop_database_success_msg, drop_result)
        self.log.info('----Opengauss_Reliability_Dbsys_Case228.py 执行结束-------')
